#include "lockfree_ringbuffer.h"
#include "../atomic/cpu_pause.h"
#include <stdlib.h>

bool ringbuffer_init(ringbuffer_t* rb, 
                    size_t capacity,
                    bool (*copy_in)(void* dest, const void* src),
                    bool (*copy_out)(void* dest, const void* src)) {
    
    // 容量必须是2的幂，便于使用位操作
    if ((capacity & (capacity - 1)) != 0) {
        // 向上取整到最近的2的幂
        capacity--;
        capacity |= capacity >> 1;
        capacity |= capacity >> 2;
        capacity |= capacity >> 4;
        capacity |= capacity >> 8;
        capacity |= capacity >> 16;
        capacity++;
    }
    
    rb->buffer = calloc(capacity, sizeof(void*));
    if (!rb->buffer) return false;
    
    rb->capacity = capacity;
    atomic_store(&rb->head, 0, memory_order_relaxed);
    atomic_store(&rb->tail, 0, memory_order_relaxed);
    rb->copy_in = copy_in;
    rb->copy_out = copy_out;
    
    return true;
}

void ringbuffer_destroy(ringbuffer_t* rb) {
    // 清理缓冲区中的数据
    size_t head = atomic_load(&rb->head, memory_order_relaxed);
    size_t tail = atomic_load(&rb->tail, memory_order_relaxed);
    
    while (head != tail) {
        void* data = rb->buffer[head & (rb->capacity - 1)];
        if (data) free(data);
        head++;
    }
    
    free(rb->buffer);
}

bool ringbuffer_write(ringbuffer_t* rb, const void* data) {
    size_t tail, next_tail;
    
    do {
        tail = atomic_load(&rb->tail, memory_order_relaxed);
        next_tail = tail + 1;
        
        // 检查缓冲区是否已满
        if ((next_tail - atomic_load(&rb->head, memory_order_acquire)) 
            > rb->capacity) {
            return false;
        }
        
    } while (!atomic_compare_exchange_weak(&rb->tail,
                                         &tail,
                                         next_tail,
                                         memory_order_release,
                                         memory_order_relaxed));
    
    // 写入数据
    size_t index = tail & (rb->capacity - 1);
    if (rb->copy_in) {
        if (!rb->copy_in(&rb->buffer[index], data)) {
            atomic_store(&rb->tail, tail, memory_order_release);
            return false;
        }
    } else {
        rb->buffer[index] = (void*)data;
    }
    
    return true;
}

bool ringbuffer_read(ringbuffer_t* rb, void* data) {
    size_t head;
    
    do {
        head = atomic_load(&rb->head, memory_order_relaxed);
        
        // 检查缓冲区是否为空
        if (head == atomic_load(&rb->tail, memory_order_acquire)) {
            return false;
        }
        
        // 读取数据
        size_t index = head & (rb->capacity - 1);
        void* item = rb->buffer[index];
        
        if (rb->copy_out) {
            if (!rb->copy_out(data, item)) {
                return false;
            }
        } else {
            *(void**)data = item;
        }
        
    } while (!atomic_compare_exchange_weak(&rb->head,
                                         &head,
                                         head + 1,
                                         memory_order_release,
                                         memory_order_relaxed));
    
    return true;
}

size_t ringbuffer_size(ringbuffer_t* rb) {
    return atomic_load(&rb->tail, memory_order_acquire) - 
           atomic_load(&rb->head, memory_order_acquire);
}

bool ringbuffer_is_empty(ringbuffer_t* rb) {
    return atomic_load(&rb->head, memory_order_acquire) == 
           atomic_load(&rb->tail, memory_order_acquire);
}

bool ringbuffer_is_full(ringbuffer_t* rb) {
    return (atomic_load(&rb->tail, memory_order_acquire) - 
            atomic_load(&rb->head, memory_order_acquire)) >= rb->capacity;
} 